import axios from 'axios'
import store from '@/store'
import router from '@/router'
import { Toast } from 'vant'

// 设置基地址
const instance = axios.create({
  baseURL: 'http://toutiao.itheima.net/'
})

//请求拦截
// 所有通过instance发送的请求都会被拦截下来
instance.interceptors.request.use(
  function (config) {
    // 给config加什么，那么请求时就有什么
    // 判断一下，有token才加
    console.log('正常请求调用的函数')
    // console.log(store.state.tokenObj.token);
    // console.log(config);
    if (store.state.tokenObj.token) {
      // 所以我们想给请求头加token，就加在headers里
      config.headers.Authorization = 'Bearer ' + store.state.tokenObj.token
    }
    return config
  },
  function (error) {
    // 对请求错误做些什么
    console.log('请求出错调用的函数')
    return Promise.reject(error)
  }
)

/*************************  响应拦截 *****************************/
//应对问题1.token2小时过期，客户会跳回登录页，影响客户体验（让页面**无感刷新**）
//应对情况2.refresh_token都过期了，需要客户重新登录（先把错误try起来，再catch让客户重新登录）

// 添加响应拦截器
//第一个参数是函数，将其中response数据返回即对响应数据做点什么，触发外面.then
//第二个参数也是函数，async与await（功能：把异步代码看起来像`同步`代码）里面return Promise.reject(error)则触发外面axios的.catch拿到错误
instance.interceptors.response.use(
  function (response) {
    return response //返回什么，axios的外面.then拿的就是response
  },
  async function (error) {
    if (error.response.status == 401) {
      //if401错误则自己处理（显示还是会报错），其他错误else抛出

      try {
        // 能进入到这里代表token有问题（14天token也过期了出现500错误，try处理500错误）

        let res = await axios({
          // 右边发请求，并拿到数据给左边的res变量
          url: 'http://toutiao.itheima.net/v1_0/authorizations',
          method: 'put',
          headers: {
            Authorization: 'Bearer ' + store.state.tokenObj.refresh_token
          } //headers要求是个对象，对象里传个刷新token
        })
        console.log('拿到新数据z', res) //拿到的请求数据
        store.commit('saveToken', {
          token: res.data.data.token, //上面请求的res->token
          refresh_token: store.state.tokenObj.refresh_token //旧的刷新token用来让客户无感登录
        }) //js里没有vue对象，需要导入store并以对象形式保存在vuex方法专用区（目前vuex主要存token,响应式存了到处都能用）

        console.dir('error打印', error) //dir打印才能查看到error(对象)，可以看到error.config的配置信息（有上面instance要的baseURL基地址）

        return await instance(error.config) //即是保存了最新token，页面还是没有变化，因为只存在vuex里,需要把之前发失败的那个请求再发一次（返回请求拦截函数的error.config配置数据）
        //instance是同时创建aixos和基地址
        //error.config对象本来是Path： /v1_0/authorizations和Method： POST
      } catch {
        //try已经处理完500错误，catch操作14天token过期后应该做的事情

        //模拟14天token过期报错操作方法：1.修改token的数字（refresh_token和token都修改）2.刷新页面3.进入到我的页面就会打回登录页了
        // 报错了，如果这里都报错了，就证明连refresh_token都过期了(目前错误是：即token和refresh_token14天有效期两个都过期了，401和500错误)
        // 那就打回登录页，让它重新登录
        router.push('/login')

        Toast.fail('登录状态已过期，请重新登录')
      }
    } else {
      return Promise.reject(error) //响应拦截功能（响应出错第二个函数， 会抛出一个报错，触发.catch，目前错误是：token过期，返回401错误）
      //拓展知识 throw Error('error')等同于return Promise.reject(error)
    }
  }
)

// 暴露出去
export default instance
